package com.snails.app.base;

import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;

import com.gyf.immersionbar.ImmersionBar;
import com.gyf.immersionbar.components.ImmersionOwner;
import com.gyf.immersionbar.components.ImmersionProxy;
import com.snails.app.R;
import com.snails.app.utils.ToastUtil;

import butterknife.ButterKnife;
import butterknife.Unbinder;

/**
 * fragment相关文章：需细读
 * Square：从今天开始抛弃Fragment吧！【http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0605/2996.html】
 * 从源码角度分析，为什么会发生Fragment重叠？【https://www.jianshu.com/p/78ec81b42f92】
 * 1、Fragment全解析系列（一）：那些年踩过的坑 【https://www.jianshu.com/p/d9143a92ad94】
 * 2、Fragment全解析系列（二）：正确的使用姿势 【https://www.jianshu.com/p/fd71d65f0ec6】
 * 3、Fragment之我的解决方案：Fragmentation 【https://www.jianshu.com/p/38f7994faa6b】
 *
 * @author lawrence
 * @date 2019-05-07 15:26
 */
public abstract class BaseFragment extends Fragment implements ImmersionOwner {
    // ----------------------------------------------------------------------------
    // ----------- abstract ------------
    // 继承类需实现方法
    // ----------------------------------------------------------------------------
    // 通过资源，设置布局
    @LayoutRes protected abstract int getLayoutId();
    // 通过创建View对象，设置布局（优先级高于getLayoutId）
    @Nullable protected abstract View getRootView();

    protected abstract void onThisCreate(@Nullable Bundle savedInstanceState);
    protected abstract void onThisViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState);
    protected abstract void initToolbar();
    protected abstract void initEventAndData();
    protected abstract void onThisDetach();

    // ----------------------------------------------------------------------------
    // ----------- static ------------
    // ----------------------------------------------------------------------------
    /**
     * 设置参数
     */
    public static <T extends BaseFragment> T setArguments(T fragment, Bundle bundle) {
        if (fragment != null && bundle != null) fragment.setArguments(bundle);
        return fragment;
    }

    // ----------------------------------------------------------------------------
    // ----------- ------------
    // ----------------------------------------------------------------------------
    private Unbinder unBinder;
    protected Activity mCtx = null;
    private ImmersionProxy mImmersionProxy = new ImmersionProxy(this);

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (activity != null) this.mCtx = activity;
    }

    @Override
    public void onAttach(Context ctx) {
        super.onAttach(ctx);
        if (ctx != null && ctx instanceof Activity) this.mCtx = (Activity) ctx;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mImmersionProxy.onCreate(savedInstanceState);
        onThisCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater,
                             @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        View rootView = getRootView();
        if (rootView == null) {
            rootView = inflater.inflate(getLayoutId(), container, false);
        }
        unBinder = ButterKnife.bind(this, rootView);
        return rootView;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        onThisViewCreated(view, savedInstanceState);
        initToolbar();
        initEventAndData();
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mImmersionProxy.onActivityCreated(savedInstanceState);
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        mImmersionProxy.setUserVisibleHint(isVisibleToUser);
    }

    @Override
    public void onResume() {
        super.onResume();
        mImmersionProxy.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mImmersionProxy.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        onThisDetach();
        mImmersionProxy.onDestroy();
        if (unBinder != null && unBinder != Unbinder.EMPTY) {
            unBinder.unbind();
        }
        unBinder = null;
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        mImmersionProxy.onHiddenChanged(hidden);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mImmersionProxy.onConfigurationChanged(newConfig);
    }

    /**
     * 懒加载，在view初始化完成之前执行
     * On lazy after view.
     */
    @Override
    public void onLazyBeforeView() { }

    /**
     * 懒加载，在view初始化完成之后执行
     * On lazy before view.
     */
    @Override
    public void onLazyAfterView() { }

    /**
     * 是否可以实现沉浸式，当为true的时候才可以执行initImmersionBar方法
     * Immersion bar enabled boolean.
     *
     * @return the boolean
     */
    @Override
    public boolean immersionBarEnabled() {
        return isImmersionBarEnabled();
    }

    /**
     * 是否可以使用沉浸式状态栏
     */
    protected boolean isImmersionBarEnabled() {
        return true;
    }

    /**
     * 默认沉浸式状态栏颜色
     */
    public void initImmersionBar() {
        //设置共同沉浸式样式
        ImmersionBar.with(this).keyboardEnable(true)
                .navigationBarColor(R.color.defaultStatusBarColor).init();
    }

    protected String $s(@StringRes int resId) {
        return getString(resId);
    }

    protected String $s(@StringRes int resId, Object... formatArgs) {
        return getString(resId, formatArgs);
    }

    public void showLongToast(String message) {
        ToastUtil.instance().showText(message, Toast.LENGTH_LONG, Gravity.CENTER);
    }

    public void showLongToast(@StringRes int resId) {
        ToastUtil.instance().showText(resId, Toast.LENGTH_LONG, Gravity.CENTER);
    }

}
